/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import connection from '@ohos.net.connection';
import { UnknownHostException } from './Error/error';

/**
 * A domain name service that resolves IP addresses for host names. Most applications will use the
 * [system DNS service][SYSTEM], which is the default. Some applications may provide their own
 * implementation to use a different DNS server, to prefer IPv6 addresses, to prefer IPv4 addresses,
 * or to force a specific known IP address.
 *
 * Implementations of this interface must be safe for concurrent use.
 */
export interface Dns {
    /**
     * Returns the IP addresses of `hostname`, in the order they will be attempted by OkHttp. If a
     * connection to an address fails, OkHttp will retry the connection with the next address until
     * either a connection is made, the set of IP addresses is exhausted, or a limit is exceeded.
     */
    lookup(hostname: string): Promise<Array<connection.NetAddress>>
}

/**
 * Internal implementation of system DNS lookup.
 * @internal
 */
class DnsSystemImpl implements Dns {
    async lookup(hostname: string): Promise<Array<connection.NetAddress>> {
        try {
            return await connection.getAddressesByName(hostname);
        } catch (err) {
            // Handle potential system errors during DNS lookup
            const error = err as Error;
            throw new UnknownHostException(`DNS lookup failed for ${hostname}: ${error.message || 'Unknown error'}`);
        }
    }
}

/**
 * A DNS that uses [connection.getAddressesByName] to ask the underlying operating system to
 * lookup IP addresses. Most custom [Dns] implementations should delegate to this instance.
 */
export const SYSTEM: Dns = new DnsSystemImpl()

/**
 * @deprecated Use SYSTEM constant instead. This class is exposed for compatibility only.
 */
export class DnsSystem implements Dns {
    static SYSTEM: Dns = SYSTEM
    
    async lookup(hostname: string): Promise<Array<connection.NetAddress>> {
        return SYSTEM.lookup(hostname);
    }
}



